from typing import Any

from aiogram import F, types
from aiogram_dialog import Dialog, DialogManager, StartMode, Window
from aiogram_dialog.widgets.input import TextInput
from aiogram_dialog.widgets.kbd import Button, Start
from sqlalchemy.ext.asyncio import AsyncSession

from app.bot.dialog.dialog_states import (
    BuyVPNSG,
    ClientSG,
    HelpSG,
    LanguageSG,
    MissingGeoSG,
    ProxySubscriptionSG,
    SelectProxySG,
    SoftProxySG,
    VPNRouterSG,
)
from app.bot.dialog.getters.users import user_info_getter
from app.bot.dialog.widgets import LocaleText
from app.bot.handlers.admin.start import start_admin
from app.bot.handlers.client.profile import user_profile
from app.bot.services.locale import Locale
from app.database.services.users import create_user, get_user, reg_user


async def register_user(
    message: types.Message, widget: Any, manager: DialogManager, email: str
):

    locale: Locale = manager.middleware_data["locale"]
    db_session = manager.middleware_data.get("db_session")

    email = str(email)
    if "@" not in email:
        await message.answer(locale.get("wrong-email"))
        return

    await reg_user(db_session, message.from_user.id, email)
    await message.answer(locale.get("register-success"))

    await manager.switch_to(ClientSG.start)


start_window = Window(
    LocaleText("welcome", user="{event.from_user.username}"),
    Start(
        LocaleText("buy-proxy-btn"),
        id="buy_proxy_button",
        state=SelectProxySG.list_proxy_types,
    ),
    Start(
        LocaleText("test-proxy-btn"),
        id="test_proxy",
        state=SelectProxySG.list_proxy_types,
        data={"for_test": True},
        when=F["test_proxy_available"],
    ),
    Start(
        LocaleText("proxy-subscription-btn"),
        id="manage_proxy_subscription",
        state=ProxySubscriptionSG.show_info,
    ),
    Start(
        LocaleText("buy-vpn-btn"),
        id="buy_vpn_button",
        state=BuyVPNSG.show_info,
    ),
    Start(
        LocaleText("buy-vpn-router-btn"),
        id="vpn_router_btn",
        state=VPNRouterSG.show_info,
    ),
    Start(
        LocaleText("change-lang-btn"),
        id="languages",
        state=LanguageSG.list_of_languages,
    ),
    Button(LocaleText("profile-btn"), id="user_profile", on_click=user_profile),
    Button(
        LocaleText("admin-btn"),
        id="admin_panel",
        on_click=start_admin,
        when=F["is_admin"],
    ),
    Start(LocaleText("help-btn"), id="help", state=HelpSG.show_help_info),
    Start(LocaleText("soft-proxy-btn"), id="soft_proxy", state=SoftProxySG.show_info),
    Start(
        LocaleText("missing-geo-btn"),
        id="missing_geo",
        state=MissingGeoSG.show_missing_geo_msg,
    ),
    state=ClientSG.start,
    getter=user_info_getter,
)

reg_window = Window(
    LocaleText("enter-email"),
    TextInput("email_address", str, on_success=register_user),
    state=ClientSG.register,
)


async def start(
    message: types.Message, dialog_manager: DialogManager, db_session: AsyncSession
):
    """
    This handler will be called when user sends `/start` command
    Main menu.
    """

    user_id = message.from_user.id
    username = message.from_user.username

    user = await get_user(db_session, user_id, True)

    if not user:
        await create_user(db_session, user_id=user_id, username=username)

    if user and user.is_registered:
        await dialog_manager.start(ClientSG.start, mode=StartMode.RESET_STACK)
    else:
        await dialog_manager.start(ClientSG.register, mode=StartMode.RESET_STACK)


start_dialog = Dialog(start_window, reg_window)
